package com.niiwoo.civet.mobile.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.niiwoo.civet.mobile.util.ParameterValidator;
import com.niiwoo.civet.mobile.vo.request.user.ThirdBindRequestVO;
import com.niiwoo.civet.mobile.vo.request.user.ThirdLoginRequestVO;
import com.niiwoo.civet.mobile.vo.request.user.ThirdUnBindRequestVO;
import com.niiwoo.civet.mobile.vo.response.user.LoginResponseNewVO;
import com.niiwoo.civet.mobile.vo.response.user.LoginResponseVO;
import com.niiwoo.civet.user.constants.LoginAccountErrorCode;
import com.niiwoo.civet.user.dto.request.LoginAccountRegisterRequestDTO;
import com.niiwoo.civet.user.dto.request.PostLoginRequestDTO;
import com.niiwoo.civet.user.dto.request.ThirdLoginRequestDTO;
import com.niiwoo.civet.user.dto.response.AccountMappingDTO;
import com.niiwoo.civet.user.dto.response.ThirdLoginResponseDTO;
import com.niiwoo.civet.user.enums.CheckThirdBindEnum;
import com.niiwoo.civet.user.enums.UserEnum;
import com.niiwoo.civet.user.enums.UserSMSTypeEnum;
import com.niiwoo.civet.user.service.UserLoginAccountDubboService;
import com.niiwoo.tripod.base.component.AsyncHttpClients;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.base.helper.StringHelper;
import com.niiwoo.tripod.consumer.component.FileUploadHandler;
import com.niiwoo.tripod.consumer.helper.Exceptions;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.web.annotation.AuthIgnore;
import com.niiwoo.tripod.web.enums.DeviceTypeEnum;
import com.niiwoo.tripod.web.properties.ShiroProperties;
import com.niiwoo.tripod.web.shiro.ThirdOpenIdToken;
import com.niiwoo.tripod.web.util.PrincipalContext;
import com.niiwoo.tripod.web.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.util.EntityUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/third")
@Slf4j
@Api(tags = "第三方登录（刘金平）", description = "/third")
public class ThirdLoginController {

    @Reference(version = "1.0.0")
    private UserLoginAccountDubboService userLoginAccountService;

    @Autowired
    private ShiroProperties shiroProperties;

    @Autowired
    PrivacyMasks privacyMasks;

    @Autowired
    AsyncHttpClients asyncHttpClients;

    @Autowired
    FileUploadHandler fileUploadHandler;

    @PostMapping("/login")
    @ApiOperation("第三方登录")
    @AuthIgnore
    public Result<LoginResponseVO> thirdLogin(@RequestBody @Valid ThirdLoginRequestVO vo) throws Throwable {
        /*if (vo.getDeviceType() != UserEnum.RegisterDeviceType.WEB.getValue().intValue() && StringUtils.isBlank(vo.getJiGuangPushId())) {
            throw new BizException(LoginAccountErrorCode.JI_GUANG_PUSH_ID_IS_EMPTY);
        }*/
        LoginResponseVO response = new LoginResponseVO();
        ThirdLoginRequestDTO requestDTO = new ThirdLoginRequestDTO();
        requestDTO.setOpenId(vo.getOpenId());
        requestDTO.setPlatformId(vo.getPlatformId());
        requestDTO = userLoginAccountService.hasBindOpenId(requestDTO);
        response.setBindType(requestDTO.getBindType());
        if(requestDTO.getBindType().equals(CheckThirdBindEnum.CAN_LOGIN.getCode())){
            shiroHandle(vo.getOpenId(), vo.getPlatformId(), DeviceTypeEnum.enumOf(vo.getDeviceType().toString()));
            response.setToken(SecurityUtils.getSubject().getSession().getId().toString());
            response.setLastLoginTime(new Date());
            response.setLoginMobileNo(requestDTO.getMobileNo());
            response.setUserId(String.valueOf(PrincipalContext.getUserId()));
            vo.setLoginMobileNo(requestDTO.getMobileNo());
            postLoginHandle(vo);
        }
        return Result.with(response);
    }

    @PostMapping("/bindOpenId")
    @ApiOperation("第三方登录绑定")
    @AuthIgnore
    public Result<LoginResponseVO> bindOpenId(@RequestBody @Valid ThirdBindRequestVO vo)  throws Throwable {
        /*if (vo.getDeviceType() != UserEnum.RegisterDeviceType.WEB.getValue().intValue() && StringUtils.isBlank(vo.getJiGuangPushId())) {
            throw new BizException(LoginAccountErrorCode.JI_GUANG_PUSH_ID_IS_EMPTY);
        }*/
        LoginResponseVO response = new LoginResponseVO();
        //校验短信验证码
        String mobileNo = vo.getLoginMobileNo();
        userLoginAccountService.validSMSCode(mobileNo, vo.getSmsCode(), UserSMSTypeEnum.BIND_THIRD_PART_ACCOUNT);

        String openId = vo.getOpenId();
        Byte platformId = vo.getPlatformId();
        Integer userDeviceType = vo.getDeviceType();
        String appId = vo.getAppId();
        AccountMappingDTO accountMappingDTO = userLoginAccountService.queryAccountMapping(privacyMasks.encryptPrivacy(mobileNo));
        ThirdLoginRequestDTO requestDTO = new ThirdLoginRequestDTO();
        if(accountMappingDTO!=null) { //校验是否已绑定其它第三方帐号
            requestDTO.setUserId(accountMappingDTO.getUserId());
            boolean isExists = userLoginAccountService.isExistsOtherOpenIdNew(accountMappingDTO.getUserId(),openId, platformId);
            if(isExists) {
                throw new BizException(LoginAccountErrorCode.EXISTS_OTHER_THIRD_ACCOUNT);
            }
        }
        String headImage = vo.getHeadImage();
        if(headImage!=null && headImage.startsWith("http:")){
            headImage = fileUploadHandler.upload(downloadFile(vo.getHeadImage()).join(), false).getImageUrl();
            vo.setHeadImage(headImage);
        }
        String nickName = vo.getNickName();
        if(nickName==null){
            nickName = "niiwoo" + StringHelper.genRandomStr(10);
        }else {
            nickName = ParameterValidator.emojiConvert(nickName);
            nickName = nickName.substring(0,ParameterValidator.trimGBK(nickName,16));
        }

        requestDTO.setOpenId(openId);
        requestDTO.setPlatformId(platformId);
        requestDTO.setMobileNo(vo.getLoginMobileNo());
        requestDTO.setThirdHeadImage(headImage);
        requestDTO.setThirdNickName(nickName);
        requestDTO.setAppId(appId);
        if (accountMappingDTO == null) { //如果不存在注册
            // 参数校验
            UserEnum.RegisterDeviceType deviceType = userDeviceType == null ? null : UserEnum.RegisterDeviceType.enumOf(userDeviceType.byteValue());
            if (deviceType == null) {
                Exceptions.throwBizException(LoginAccountErrorCode.DEVICE_TYPE_ERROR);
            }
            nickName = userLoginAccountService.getValidNickName(nickName);
            vo.setNickName(nickName);
            LoginAccountRegisterRequestDTO dto = getLoginAccountRegisterRequestDTO(vo, deviceType);
            // 注册
            String userId = userLoginAccountService.register(dto);
            if (userId == null) {
                throw new BizException(LoginAccountErrorCode.REGISTER_FAIL);
            }
            requestDTO.setUserId(userId);
            userLoginAccountService.insertNickName(nickName);
        }
        boolean bindFlag = userLoginAccountService.bindOpenId(requestDTO);
        if(bindFlag) { //绑定成功
            String deviceType = getDeviceType(userDeviceType);
            shiroHandle(vo.getOpenId(), vo.getPlatformId(), DeviceTypeEnum.enumOf(deviceType));
            response.setToken(SecurityUtils.getSubject().getSession().getId().toString());
            response.setLastLoginTime(new Date());
            response.setLoginMobileNo(vo.getLoginMobileNo());
            response.setUserId(String.valueOf(PrincipalContext.getUserId()));
            postLoginHandle(vo);
        }
        return Result.with(response);
    }

    @PostMapping("/bindOpenIdNew")
    @ApiOperation("第三方登录绑定（返回是否为绑定或注册登录方式）")
    @AuthIgnore
    public Result<LoginResponseNewVO> bindOpenIdNew(@RequestBody @Valid ThirdBindRequestVO vo)  throws Throwable {
        /*if (vo.getDeviceType() != UserEnum.RegisterDeviceType.WEB.getValue().intValue() && StringUtils.isBlank(vo.getJiGuangPushId())) {
            throw new BizException(LoginAccountErrorCode.JI_GUANG_PUSH_ID_IS_EMPTY);
        }*/
        LoginResponseNewVO response = new LoginResponseNewVO();
        //校验短信验证码
        String mobileNo = vo.getLoginMobileNo();
        userLoginAccountService.validSMSCode(mobileNo, vo.getSmsCode(), UserSMSTypeEnum.BIND_THIRD_PART_ACCOUNT);

        String openId = vo.getOpenId();
        Byte platformId = vo.getPlatformId();
        Integer userDeviceType = vo.getDeviceType();
        AccountMappingDTO accountMappingDTO = userLoginAccountService.queryAccountMapping(privacyMasks.encryptPrivacy(mobileNo));
        ThirdLoginRequestDTO requestDTO = new ThirdLoginRequestDTO();
        if(accountMappingDTO!=null) { //校验是否已绑定其它第三方帐号
            requestDTO.setUserId(accountMappingDTO.getUserId());
            boolean isExists = userLoginAccountService.isExistsOtherOpenIdNew(accountMappingDTO.getUserId(),openId, platformId);
            if(isExists) {
                throw new BizException(LoginAccountErrorCode.EXISTS_OTHER_THIRD_ACCOUNT);
            }
        }
        String headImage = vo.getHeadImage();
        if(headImage!=null && headImage.startsWith("http:")){
            headImage = fileUploadHandler.upload(downloadFile(vo.getHeadImage()).join(), false).getImageUrl();
            vo.setHeadImage(headImage);
        }
        String nickName = vo.getNickName();
        if(nickName==null){
            nickName = "niiwoo" + StringHelper.genRandomStr(10);
        }else {
            nickName = ParameterValidator.emojiConvert(nickName);
            nickName = nickName.substring(0,ParameterValidator.trimGBK(nickName,16));
        }

        requestDTO.setOpenId(openId);
        requestDTO.setPlatformId(platformId);
        requestDTO.setMobileNo(vo.getLoginMobileNo());
        requestDTO.setThirdHeadImage(headImage);
        requestDTO.setThirdNickName(nickName);
        response.setLoginType((byte) 1);
        if (accountMappingDTO == null) { //如果不存在注册
            // 参数校验
            UserEnum.RegisterDeviceType deviceType = userDeviceType == null ? null : UserEnum.RegisterDeviceType.enumOf(userDeviceType.byteValue());
            if (deviceType == null) {
                Exceptions.throwBizException(LoginAccountErrorCode.DEVICE_TYPE_ERROR);
            }
            nickName = userLoginAccountService.getValidNickName(nickName);
            vo.setNickName(nickName);
            LoginAccountRegisterRequestDTO dto = getLoginAccountRegisterRequestDTO(vo, deviceType);
            // 注册
            String userId = userLoginAccountService.register(dto);
            if (userId == null) {
                throw new BizException(LoginAccountErrorCode.REGISTER_FAIL);
            }
            requestDTO.setUserId(userId);
            response.setLoginType((byte) 3);
            userLoginAccountService.insertNickName(nickName);
        }
        boolean bindFlag = userLoginAccountService.bindOpenId(requestDTO);
        if(bindFlag) { //绑定成功
            String deviceType = getDeviceType(userDeviceType);
            shiroHandle(vo.getOpenId(), vo.getPlatformId(), DeviceTypeEnum.enumOf(deviceType));
            response.setToken(SecurityUtils.getSubject().getSession().getId().toString());
            response.setLastLoginTime(new Date());
            response.setLoginMobileNo(vo.getLoginMobileNo());
            response.setUserId(String.valueOf(PrincipalContext.getUserId()));
            postLoginHandle(vo);
            if(accountMappingDTO != null) {
                response.setLoginType((byte) 2);
            }
        }
        return Result.with(response);
    }


    @PostMapping("/getMyBindList")
    @ApiOperation("第三方帐号关联列表")
    public Result<List<ThirdLoginResponseDTO>> getMyBindList(){
        String userId = String.valueOf(PrincipalContext.getUserId());
        List<ThirdLoginResponseDTO> responseDTOList = userLoginAccountService.getMyBindList(userId);
        return Result.with(responseDTOList);
    }

    @PostMapping("/unbindOpenId")
    @ApiOperation("第三方登录解绑")
    public Result<Boolean> unbindOpenId(@RequestBody @Valid ThirdUnBindRequestVO vo){
        ThirdLoginRequestDTO requestDTO = new ThirdLoginRequestDTO();
        requestDTO.setOpenId(vo.getOpenId());
        requestDTO.setPlatformId(vo.getPlatformId());
        boolean bindFlag = userLoginAccountService.unbindOpenId(requestDTO);
        return Result.with(bindFlag);
    }


    /**
     * 获取随机盐值
     *
     * @return 盐值
     */
    private String getRandomSalt(int longth) {
        return StringHelper.genRandomStr(longth);
    }

    /**
     * 获取密码哈希值
     *
     * @param password 密码明文
     * @param salt     盐值
     * @return 密码哈希值
     */
    private String getPasswordHash(String password, String salt) {
        ShiroProperties.HashedCredentialProperties hashedCredential = shiroProperties.getHashedCredential();
        return new SimpleHash(hashedCredential.getHashAlgorithName(), ParameterValidator.toTuanDaiPassword(password), salt, hashedCredential.getHashIterations()).toString();
    }

    private LoginAccountRegisterRequestDTO getLoginAccountRegisterRequestDTO(ThirdBindRequestVO vo, UserEnum.RegisterDeviceType deviceType) {
        LoginAccountRegisterRequestDTO dto = new LoginAccountRegisterRequestDTO();
        String salt = getRandomSalt(5);
        // 登录手机号
        dto.setLoginMobileNo(vo.getLoginMobileNo());
        // 盐值
        dto.setSalt(salt);
        // 密码哈希值
        dto.setPassword(getPasswordHash(vo.getPassword() == null ? getRandomSalt(8) : vo.getPassword(), salt));
        // 短信验证码
        dto.setSmsCode(vo.getSmsCode());
        // 邀请人手机号
        dto.setInviterMobileNo(vo.getInviterMobileNo());
        // 省级名称
        dto.setProvinceName(vo.getProvinceName());
        // 市级名称
        dto.setCityName(vo.getCityName());
        // 区级名称
        dto.setAreaName(vo.getAreaName());
        // 详细地址
        dto.setAddress(vo.getAddress());
        // 经度
        dto.setLongitude(vo.getLongitude());
        // 纬度
        dto.setLatitude(vo.getLatitude());
        // APP版本
        dto.setAppVersion(vo.getAppVersion());
        // 设备类型
        dto.setDeviceType(deviceType);
        // 注册渠道
        switch (deviceType) {
            case IOS:
                dto.setRegisterChannel(UserEnum.RegisterChannel.PLATFORM_APP_IOS); break;
            case ANDROID:
                dto.setRegisterChannel(UserEnum.RegisterChannel.PLATFORM_APP_ANDROID); break;
            case WEB:
                dto.setRegisterChannel(UserEnum.RegisterChannel.PLATFORM_H5); break;
        }
        // APP下载渠道
        dto.setAppDownloadChannel(vo.getAppDownloadChannel());

        dto.setIpAddress(vo.getIpAddress());
        dto.setLongitude(vo.getLongitude());
        dto.setLatitude(vo.getLatitude());
        dto.setMapType(vo.getMapType());
        dto.setMacAddress(vo.getMacAddress());
        dto.setOperators(vo.getOperators());
        if (!"unknown".equals(vo.getWifiSSID())) {
            dto.setWifiSSID(vo.getWifiSSID());
        }
        dto.setDownChannel(vo.getDownChannel());
        dto.setAppVersion(vo.getAppVersion());
        if (!"000".equals(vo.getDeviceId())) {
            dto.setDeviceId(vo.getDeviceId());
        }
        dto.setSimMobilePhone(vo.getSimMobilePhone());
        dto.setOs(vo.getOs());
        dto.setOsVersion(vo.getOs());
        dto.setResolution(vo.getResolution());
        dto.setBrand(vo.getBrand());
        dto.setPhoneModel(vo.getPhoneModel());
        dto.setEquipmentStatus(vo.getEquipmentStatus());
        dto.setDualSim(vo.getDualSim());
        dto.setHeadImage(vo.getHeadImage());
        dto.setNickName(vo.getNickName());
        dto.setInviterUserId(vo.getInviterUserId());
        dto.setFestivalFlag(vo.getFestivalFlag());
        dto.setRecommendUrl(vo.getRecommendUrl());
        return dto;
    }

    private void shiroHandle(String openId, Byte platformId, DeviceTypeEnum deviceTypeEnum) throws Throwable {
        ThirdOpenIdToken token = new ThirdOpenIdToken(openId, platformId, deviceTypeEnum);
        try {
            // 登录验证
            SecurityUtils.getSubject().login(token);
        }catch (UnknownAccountException e) {
            // 账号不存在
            Exceptions.throwBizException(LoginAccountErrorCode.THIRD_AUTH_FAIL);
        } catch (IncorrectCredentialsException e) {
            // 密码错误处理
            Exceptions.throwBizException(LoginAccountErrorCode.THIRD_AUTH_FAIL);
        } catch (Exception e) {
            // 其他业务异常
            Exceptions.throwBizException(LoginAccountErrorCode.THIRD_AUTH_FAIL);
        }
    }

    private String getDeviceType(Integer userDeviceType) {
        String deviceType = "";
        if(userDeviceType == 0){
            deviceType = DeviceTypeEnum.ANDROID_MOBILE.getDesc();
        }else if(userDeviceType == 1){
            deviceType = DeviceTypeEnum.IOS_MOBILE.getDesc();
        }else if(userDeviceType == 2){
            deviceType = DeviceTypeEnum.H5.getDesc();
        }
        return deviceType;
    }

    /**
     * 登录后处理
     */
    private void postLoginHandle(ThirdLoginRequestVO request) {
        PostLoginRequestDTO postLoginRequestDTO = new PostLoginRequestDTO();
        postLoginRequestDTO.setIsPasswordError(false);
        postLoginRequestDTO.setLoginMobileNo(request.getLoginMobileNo());
        if (!postLoginRequestDTO.getIsPasswordError()) {
            postLoginRequestDTO.setProvinceName(request.getProvinceName());
            postLoginRequestDTO.setCityName(request.getCityName());
            postLoginRequestDTO.setAreaName(request.getAreaName());
            postLoginRequestDTO.setAddress(request.getAddress());
            postLoginRequestDTO.setLongitude(request.getLongitude());
            postLoginRequestDTO.setLatitude(request.getLatitude());
            postLoginRequestDTO.setClientAccessIP(request.getClientAccessIP());

            postLoginRequestDTO.setMapType(request.getMapType());
            postLoginRequestDTO.setMacAddress(request.getMacAddress());
            if (!"unknown".equals(request.getWifiSSID())) {
                postLoginRequestDTO.setWifiSSID(request.getWifiSSID());
            }
            postLoginRequestDTO.setDownChannel(request.getDownChannel());
            postLoginRequestDTO.setAppVersion(request.getAppVersion());
            if (!"000".equals(request.getDeviceId())) {
                postLoginRequestDTO.setDeviceId(request.getDeviceId());
            }
            postLoginRequestDTO.setSimMobilePhone(request.getSimMobilePhone());
            postLoginRequestDTO.setOs(request.getOs());
            postLoginRequestDTO.setOsVersion(request.getOsVersion());
            postLoginRequestDTO.setResolution(request.getResolution());
            postLoginRequestDTO.setPhoneModel(request.getPhoneModel());
            postLoginRequestDTO.setBrand(request.getBrand());
            postLoginRequestDTO.setEquipmentStatus(request.getEquipmentStatus());
            postLoginRequestDTO.setDualSim(request.getDualSim());
            postLoginRequestDTO.setJiGuangPushId(request.getJiGuangPushId());
            postLoginRequestDTO.setBlackBox(request.getBlackBox());
            switch (request.getDeviceType()) {
                case 0 : postLoginRequestDTO.setDeviceType(UserEnum.RegisterDeviceType.ANDROID); break;
                case 1 : postLoginRequestDTO.setDeviceType(UserEnum.RegisterDeviceType.IOS); break;
                case 2 : postLoginRequestDTO.setDeviceType(UserEnum.RegisterDeviceType.WEB);
            }
        }
        userLoginAccountService.postLoginHandle(postLoginRequestDTO);
    }

    /**
     * 登录后处理
     */
    private void postLoginHandle(ThirdBindRequestVO request) {
        PostLoginRequestDTO postLoginRequestDTO = new PostLoginRequestDTO();
        postLoginRequestDTO.setIsPasswordError(false);
        postLoginRequestDTO.setLoginMobileNo(request.getLoginMobileNo());
        if (!postLoginRequestDTO.getIsPasswordError()) {
            postLoginRequestDTO.setProvinceName(request.getProvinceName());
            postLoginRequestDTO.setCityName(request.getCityName());
            postLoginRequestDTO.setAreaName(request.getAreaName());
            postLoginRequestDTO.setAddress(request.getAddress());
            postLoginRequestDTO.setLongitude(request.getLongitude());
            postLoginRequestDTO.setLatitude(request.getLatitude());
            postLoginRequestDTO.setClientAccessIP(request.getClientAccessIP());

            postLoginRequestDTO.setMapType(request.getMapType());
            postLoginRequestDTO.setMacAddress(request.getMacAddress());
            if (!"unknown".equals(request.getWifiSSID())) {
                postLoginRequestDTO.setWifiSSID(request.getWifiSSID());
            }
            postLoginRequestDTO.setDownChannel(request.getDownChannel());
            postLoginRequestDTO.setAppVersion(request.getAppVersion());
            if (!"000".equals(request.getDeviceId())) {
                postLoginRequestDTO.setDeviceId(request.getDeviceId());
            }
            postLoginRequestDTO.setSimMobilePhone(request.getSimMobilePhone());
            postLoginRequestDTO.setOs(request.getOs());
            postLoginRequestDTO.setOsVersion(request.getOsVersion());
            postLoginRequestDTO.setResolution(request.getResolution());
            postLoginRequestDTO.setPhoneModel(request.getPhoneModel());
            postLoginRequestDTO.setBrand(request.getBrand());
            postLoginRequestDTO.setEquipmentStatus(request.getEquipmentStatus());
            postLoginRequestDTO.setDualSim(request.getDualSim());
            postLoginRequestDTO.setJiGuangPushId(request.getJiGuangPushId());
            postLoginRequestDTO.setBlackBox(request.getBlackBox());
            switch (request.getDeviceType()) {
                case 0 : postLoginRequestDTO.setDeviceType(UserEnum.RegisterDeviceType.ANDROID); break;
                case 1 : postLoginRequestDTO.setDeviceType(UserEnum.RegisterDeviceType.IOS); break;
                case 2 : postLoginRequestDTO.setDeviceType(UserEnum.RegisterDeviceType.WEB);
            }
        }
        userLoginAccountService.postLoginHandle(postLoginRequestDTO);
    }

    private CompletableFuture<byte[]> downloadFile(String url) {
        CompletableFuture<byte[]> future = new CompletableFuture<>();
        asyncHttpClients.getRequest(url, new FutureCallback<HttpResponse>() {
            @Override
            public void completed(HttpResponse response) {
                try {
                    int code = response.getStatusLine().getStatusCode();
                    byte[] file = null;
                    if (code == org.apache.http.HttpStatus.SC_OK) {
                        file = EntityUtils.toByteArray(response.getEntity());
                    }
                    if (file == null || file.length == 0) {
                        throw new BizException("下载图片失败");
                    }
                    future.complete(file);
                } catch (Exception e) {
                    future.completeExceptionally(e);
                }
            }

            @Override
            public void failed(Exception e) {
                future.completeExceptionally(e);
            }

            @Override
            public void cancelled() {
                future.cancel(true);
            }
        });

        return future;
    }
}
